#include <stdlib.h>
#include <string.h>
#include "list.h"

struct LIST* l_create()
{
	struct LIST* plList = (struct LIST*) malloc(sizeof(struct LIST));
	plList->pHead = (struct VARNODE*) malloc(sizeof(struct VARNODE));
	plList->pTail = plList->pHead;
	return plList;
}

int l_append(struct LIST* plList, int iType, VARHANDLE pValue)
{
	struct VARNODE* pNode = (struct VARNODE*) malloc(sizeof(struct VARNODE));
	if (iType == INT_TYPE)
	{
		pNode->pValue = (int*) malloc(sizeof(int));
		*((int*)pNode->pValue) = *((int*)pValue);
	}
	else if (iType == STR_TYPE)
	{
		pNode->pValue = (char*) malloc(sizeof(char) * (strlen((char*)pValue) + 1));
		strcpy((char*)pNode->pValue, (char*)pValue);
	}
	pNode->iType = iType;

	pNode->pNext = NULL;
	(plList->pTail)->pNext = pNode;
	plList->pTail = pNode;

	return 1;
}

struct VARNODE* l_find(struct LIST* plList, int iType, VARHANDLE pValue)
{
	struct VARNODE *pCurrent = plList->pHead;

	while (pCurrent)
	{
		if (iType == pCurrent->iType && iType == INT_TYPE)
		{
			if (*((int*)(pCurrent->pValue)) == *(int*)pValue)
				return pCurrent;
		}
		else if (iType == pCurrent->iType && iType == STR_TYPE)
		{
			if (!strcmp((char*)(pCurrent->pValue), (char*)(pValue)))
				return pCurrent;
		}
		pCurrent = pCurrent->pNext;
	}

	return NULL;
}

void l_release(struct LIST* plList)
{
	struct VARNODE* pCurrent = plList->pHead;
	while (pCurrent)
	{
		struct VARNODE* temp = pCurrent->pNext;
		free(pCurrent);
		pCurrent = temp;
	}
	free(plList);
}

void l_remove(struct LIST* plList, struct VARNODE* pNode)
{
	struct VARNODE* pCurrent = plList->pHead;
	struct VARNODE* pPre = plList->pHead;
	while (pCurrent)
	{
		if (pCurrent == pNode)
			break;
		pPre = pCurrent;
		pCurrent = pCurrent->pNext;
	}
	if (pCurrent == NULL || pCurrent == plList->pHead)
		return;
	if (pCurrent == plList->pTail)
		plList->pTail = pPre;
	pPre->pNext = pCurrent->pNext;
	free(pCurrent);
}

void l_delete(struct LIST* plList, int iType, VARHANDLE pValue)
{
	struct VARNODE* pCurrent = plList->pHead;
	struct VARNODE* pPre = plList->pHead;
	
	while (pCurrent)
	{
		if (iType == pCurrent->iType && iType == INT_TYPE)
		{
			if (*((int*)pCurrent->pValue) == *(int*)pValue)
				break;
		}
		else if (iType == pCurrent->iType && iType == STR_TYPE)
		{
			if (!strcmp((char*)(pCurrent->pValue), (char*)pValue))
				break;
		}
		pPre = pCurrent;
		pCurrent = pCurrent->pNext;
	}

	if (pCurrent == NULL || pCurrent == plList->pHead)
		return;
	if (pCurrent == plList->pTail)
		plList->pTail = pPre;
	pPre->pNext = pCurrent->pNext;
	free(pCurrent);
}

